package cn.tutu.blockchain.fileInfo.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.tutu.blockchain.common.TypeEnum;
import cn.tutu.blockchain.fileInfo.dao.FileInfoDao;
import cn.tutu.blockchain.fileInfo.entity.FileInfo;
import cn.tutu.blockchain.fileInfo.service.FileInfoService;
import cn.tutu.blockchain.filebak.dao.FilebakDao;
import cn.tutu.blockchain.filebak.entity.Filebak;
import cn.tutu.blockchain.minemachine.dao.MinemachineDao;
import cn.tutu.blockchain.minemachine.entity.Minemachine;

@Service
@Transactional
public class FileInfoServiceImpl implements FileInfoService {

	@Autowired
	private FileInfoDao fileInfoDao;
	@Autowired
	private MinemachineDao minemachineDao;
	@Autowired
	private FilebakDao filebakDao;
	@Value("${cn.tutu.blockchain.bak.count}")
	private Integer count;

	@Override
	public synchronized void create(String minemachineId, String fileHash, String type) {

		List<FileInfo> findByModel = null;
		FileInfo fileInfo = null;

		if (type.equals(TypeEnum.MACHINE_FILE_HASH.getCode())) {
			// 添加文件信息
			fileInfo = new FileInfo(minemachineId, fileHash, type);
			findByModel = fileInfoDao.findByModel(fileInfo);
			if (null == findByModel || findByModel.size() <= 0) {
				fileInfoDao.insert(fileInfo);
			} else {
				// 更新最后修改时间
				fileInfoDao.update(findByModel.get(0));
			}
		} else {
			fileInfo = new FileInfo(minemachineId, null, type);
			findByModel = fileInfoDao.findByModel(fileInfo);
			if (null == findByModel || findByModel.size() <= 0) {
				fileInfo.setFileHash(fileHash);
				fileInfoDao.insert(fileInfo);
			} else {
				// 更新最后修改时间
				FileInfo fileInfo1 = findByModel.get(0);
				fileInfo1.setFileHash(fileHash);
				fileInfoDao.update(fileInfo1);
			}
		}

		// 添加矿机信息
		Minemachine machineInfo = new Minemachine(minemachineId);
		Minemachine findByMachineId = minemachineDao.findByMachineId(minemachineId);
		if (null == findByMachineId) {
			minemachineDao.insert(machineInfo);
		} else {
			// 更新最后修改时间
			findByMachineId.setStatus(TypeEnum.STATUS_Y.getCode());
			minemachineDao.update(findByMachineId);
		}
	}

	@Override
	public synchronized List<String> getFileHashByMacId(String minemachineId) {
		// 1、在FileInfo中找出备份次数不满足要求并且没有被矿机备份过的文件
		List<FileInfo> fileInfoList = fileInfoDao.findNeedBackByMacId(minemachineId, count);
		// 需要备份的文件hash
		List<String> strList = new ArrayList<String>();
		// 需要更新备份次数的文件信息
		List<FileInfo> bakList = new ArrayList<FileInfo>();

		// 2、在备份表中根据矿机ID找出该矿机已经备份过的文件
		List<String> filebakList = filebakDao.findBakDoneByMacId(minemachineId);
		// 3、遍历1、2中找出的hash值，如果有相同的就剔除
		for (FileInfo fileInfo : fileInfoList) {
			String fileHash = fileInfo.getFileHash();
			strList.add(fileHash);
			fileInfo.setCount(fileInfo.getCount() + 1);
			bakList.add(fileInfo);
			if (null != filebakList && filebakList.size() > 0) {
				for (String str : filebakList) {
					// 如果该文件没有被本矿机备份过就备份
					if (str.equals(fileHash)) {
						strList.remove(fileHash);
						bakList.remove(fileInfo);
					}
				}
			}
		}
		// fileInfoList.removeAll(filebakList);
		// 添加备份信息
		if (null != strList && strList.size() > 0) {
			filebakDao.insertBatch(strList, minemachineId);
		}
		// 修改备份次数
		if (null != bakList && bakList.size() > 0) {
			fileInfoDao.updateBatch(bakList);
		}

		// 修改该矿机的状态

		Minemachine findByMachineId = minemachineDao.findByMachineId(minemachineId);
		if (null == findByMachineId) {
			Minemachine mac = new Minemachine();
			mac.setStatus(TypeEnum.STATUS_Y.getCode());
			mac.setMineMachineId(minemachineId);
			minemachineDao.insert(mac);
		} else {
			// 更新最后修改时间
			findByMachineId.setStatus(TypeEnum.STATUS_Y.getCode());
			minemachineDao.update(findByMachineId);
		}
		return strList;
	}

	@Override
	public String getRootHashByMacId(String minemachineId) {
		return fileInfoDao.findByMacIdAndType(minemachineId, TypeEnum.MACHINE_ROOT_HASH.getCode());

	}

	@Override
	public void updaeCountBatch(List<Filebak> bakList) {
		fileInfoDao.updaeCountBatch(bakList);
	}

}
